package com.qianli.cashmama.trade.domain.services.impl;

import com.qianli.cashmama.trade.common.enums.*;
import com.qianli.cashmama.trade.common.error.TradeErrorCodeEnum;
import com.qianli.cashmama.trade.common.exceptions.TradeException;
import com.qianli.cashmama.trade.common.utils.RebindCardUtil;
import com.qianli.cashmama.trade.domain.model.BizRecord;
import com.qianli.cashmama.trade.domain.model.TradeBase;
import com.qianli.cashmama.trade.domain.model.TradeTaskCenter;
import com.qianli.cashmama.trade.domain.services.TradeBaseService;
import com.qianli.cashmama.trade.helper.LoanDataCreateHelper;
import com.qianli.cashmama.trade.integration.notification.message.MessageIntegrationService;
import com.qianli.cashmama.trade.integration.pay.PayIntegrationService;
import com.qianli.cashmama.trade.integration.pay.dto.TradePayDto;
import com.qianli.cashmama.trade.repo.BizRecordRepository;
import com.qianli.cashmama.trade.repo.TimeoutRepository;
import com.qianli.cashmama.trade.repo.TradeTaskCenterRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;

/**
 * Created with IntelliJ IDEA.
 * User: sm
 * Date: 2017/7/20
 * Time: 下午4:37
 */
@Service
public class TradeBaseServiceImpl implements TradeBaseService {
    private static final Logger LOGGER = LoggerFactory.getLogger(TradeBaseServiceImpl.class);

    @Autowired
    private TradeTaskCenterRepository tradeTaskCenterRepository;

    @Autowired
    private PayIntegrationService payIntegrationService;

    @Autowired
    private LoanDataCreateHelper loanDataCreateHelper;
    @Autowired
    private BizRecordRepository bizRecordRepository;

    @Override
    public TradeBase createTrade(TradeBase tradeBase) {
        tradeBase.transferStatus(com.qianli.cashmama.trade.common.enums.TradeActionEnum.CREATED.getCode(),
                com.qianli.cashmama.trade.common.enums.TradeStatusEnum.CREATE_SUCCESS.getStatus(), "jeff", new Date(), new Date(), "storeList trade");
        return tradeBase;
    }

    /**
     * 创建支付任务
     *
     * @param tradeBase
     * @param isRebindCard
     */
    @Override
    public void createPayTask(TradeBase tradeBase, boolean isRebindCard) {
        try {
            String bizNo = null;
            //如果是重新绑卡，则打款任务使用新的业务编号,用（交易编号+ '_1'）组成, 保证一个用户最多触发一次重绑卡
            if (isRebindCard) {
                bizNo = RebindCardUtil.getRebindCardOutNo(tradeBase.getTradeNo());
                BizRecord bizRecord = bizRecordRepository.load(bizNo);
                if (bizRecord != null) {
                    LOGGER.error("重复重绑卡拦截,tradeNo:{}", tradeBase.getTradeNo());
                    throw new TradeException(TradeErrorCodeEnum.push_to_loan_failed, "请勿重复重绑卡");
                }
            }
            TradePayDto tradePayDto = loanDataCreateHelper.createTradePayDto(tradeBase, bizNo);

            boolean pushSuccess = payIntegrationService.pushTradeToPay(tradePayDto, tradeBase.getProductCategory());
            if (!pushSuccess) {
                TradeTaskCenter tradeTaskCenter = new TradeTaskCenter()
                        .setTaskRetryTimes(0)
                        .setTaskStatus(TaskStatusEnum.INIT)
                        .setTaskType(TaskTypeEnum.PAY)
                        .setTradeNo(tradeBase.getTradeNo())
                        .setBizNo(tradePayDto.getBizNo());
                tradeTaskCenterRepository.store(tradeTaskCenter);
            }
        } catch (Exception e) {
            LOGGER.error("== 推送到放款发生异常 ==,tradeNo:{},e", tradeBase.getTradeNo(), e);
            throw new com.qianli.cashmama.trade.common.exceptions.TradeException(com.qianli.cashmama.trade.common.error.TradeErrorCodeEnum.push_to_loan_failed, "推送到放款发生异常");
        }
    }

    @Override
    public void closeAuditRejectTrade(TradeBase tradeBase) {
        tradeBase.transferStatus(com.qianli.cashmama.trade.common.enums.TradeActionEnum.AUDIT_RECEIPT.getCode(),
                TradeStatusEnum.AUDIT_REJECT.getStatus(), "jeff", new Date(), new Date(), "AUDIT FAILED,CLOSED");
        tradeBase.setTradeAuditStatus(com.qianli.cashmama.trade.common.enums.TradeAuditStatusEnum.AUDIT_FAILED);
    }

    @Override
    public void waitingForHighMark(TradeBase tradeBase) {
        tradeBase.transferStatus(com.qianli.cashmama.trade.common.enums.TradeActionEnum.REQUEST_HIGH_MARK.getCode(),
                TradeStatusEnum.AUDIT_REJECT.getStatus(), "jeff", new Date(), new Date(), "AUDIT FAILED,CLOSED");
    }

    @Override
    public void highMarkPass(TradeBase tradeBase) {
        tradeBase.transferStatus(TradeActionEnum.HIGH_MARK_PASS.getCode(),
                TradeStatusEnum.LOAN_WAITTING.getStatus(), "jeff", new Date(), new Date(), "AUDIT FAILED,CLOSED");

        tradeBase.setTradeAuditStatus(TradeAuditStatusEnum.AUDIT_SUCCESS);
    }

    @Override
    public void highMarkReject(TradeBase tradeBase) {
        tradeBase.transferStatus(TradeActionEnum.HIGH_MARK_REJECT.getCode(),
                TradeStatusEnum.AUDIT_REJECT.getStatus(), "jeff", new Date(), new Date(), "AUDIT FAILED,CLOSED");
        tradeBase.setTradeAuditStatus(TradeAuditStatusEnum.AUDIT_FAILED);
    }

    /**
     * 信审通过订单
     */
    @Override
    public void auditPassToEsign(TradeBase tradeBase) {
        tradeBase.transferStatus(com.qianli.cashmama.trade.common.enums.TradeActionEnum.SIGN_RECEIPT.getCode(),
                com.qianli.cashmama.trade.common.enums.TradeStatusEnum.LOAN_WAITTING.getStatus(), "jeff", new Date(), new Date(), "AUDIT SUCCESS,wait e-sign");
        //设置信审状态
        tradeBase.setTradeAuditStatus(TradeAuditStatusEnum.AUDIT_SUCCESS);
    }

    @Override
    public void auditPass(TradeBase tradeBase) {
        tradeBase.transferStatus(TradeActionEnum.AUDIT_RECEIPT.getCode(),
                TradeStatusEnum.LOAN_WAITTING.getStatus(), "jeff", new Date(), new Date(), "AUDIT SUCCESS,paying");
        //设置信审状态
        tradeBase.setTradeAuditStatus(TradeAuditStatusEnum.AUDIT_SUCCESS);
    }

    /**
     * 信审通过（到待用户提现）
     *
     * @param tradeBase
     */
    @Override
    public void auditPassToWithdraw(TradeBase tradeBase) {
        tradeBase.transferStatus(TradeActionEnum.AUDIT_RECEIPT.getCode(),
                TradeStatusEnum.PENDING_WITHDRAWAL.getStatus(), "jeff", new Date(), new Date(), "AUDIT SUCCESS,wait withdraw");
        //设置信审状态
        tradeBase.setTradeAuditStatus(TradeAuditStatusEnum.AUDIT_SUCCESS);
    }

    /**
     * 提现确认（到待打款）
     *
     * @param tradeBase
     */
    @Override
    public void withdrawalConfirm(TradeBase tradeBase) {
        tradeBase.transferStatus(TradeActionEnum.WITHDRAWAL_CONFIRM.getCode(),
                TradeStatusEnum.LOAN_WAITTING.getStatus(), "jeff", new Date(), new Date(), "USER CONFIRM,paying");
    }

    @Override
    public void paymentSuccess(TradeBase tradeBase) {
        tradeBase.transferStatus(com.qianli.cashmama.trade.common.enums.TradeActionEnum.PAID_RECEIPT.getCode(),
                com.qianli.cashmama.trade.common.enums.TradeStatusEnum.REPAYMENT_WATTING.getStatus(), "jeff", new Date(), new Date(), "PAY SUCCESS");
        tradeBase.setTradePayStatus(com.qianli.cashmama.trade.common.enums.TradePayStatusEnum.PAY_SUCCESS);

    }

    @Override
    public void loanFailed(TradeBase tradeBase, boolean payRetry) {
        if (payRetry) {
            tradeBase.transferStatus(com.qianli.cashmama.trade.common.enums.TradeActionEnum.PAY_CASH_RECEIPT.getCode(),
                    com.qianli.cashmama.trade.common.enums.TradeStatusEnum.PAY_RETRY.getStatus(), "jeff", new Date(), new Date(), "retry PAY");
        } else {
            tradeBase.transferStatus(com.qianli.cashmama.trade.common.enums.TradeActionEnum.PAY_CASH_RECEIPT.getCode(),
                    com.qianli.cashmama.trade.common.enums.TradeStatusEnum.PAY_RETRY.getStatus(), "jeff", new Date(), new Date(), "PAY FAILED CLOSED");
        }

        tradeBase.setTradePayStatus(com.qianli.cashmama.trade.common.enums.TradePayStatusEnum.PAY_FAILED);
    }

    /**
     * 签名成功
     */
    @Override
    public void signSuccess(TradeBase tradeBase) {
        tradeBase.transferStatus(com.qianli.cashmama.trade.common.enums.TradeActionEnum.SIGN_RECEIPT.getCode(),
                com.qianli.cashmama.trade.common.enums.TradeStatusEnum.LOAN_WAITTING.getStatus(), "system", new Date(), new Date(), "SIGN SUCCESS");
        tradeBase.setTradeSignStatus(TradeSignStatusEnum.SIGN_SUCCESS);
    }

    /**
     * 签名失败
     *
     * @param tradeBase
     */
    @Override
    public void signFailed(TradeBase tradeBase) {
        tradeBase.transferStatus(com.qianli.cashmama.trade.common.enums.TradeActionEnum.SIGN_RECEIPT.getCode(),
                TradeStatusEnum.AUDIT_REJECT.getStatus(), "jeff", new Date(), new Date(), "close trade");
        tradeBase.setTradeSignStatus(TradeSignStatusEnum.SIGN_FAILED);
    }

    /**
     * 签名超时关闭
     *
     * @param tradeBase
     */
    @Override
    public void signTimeOut(TradeBase tradeBase) {
        tradeBase.transferStatus(com.qianli.cashmama.trade.common.enums.TradeActionEnum.SIGN_RECEIPT.getCode(),
                com.qianli.cashmama.trade.common.enums.TradeStatusEnum.AUDIT_REJECT.getStatus(), "jeff", new Date(), new Date(), "ORDER_TIMEOUT,CLOSED");
        tradeBase.setTradeSignStatus(TradeSignStatusEnum.SIGN_TIMEOUT);
    }

    private Long addTradeTaskCenter(String tradeNo, TaskTypeEnum taskTypeEnum) {
        TradeTaskCenter tradeTaskCenter = new TradeTaskCenter()
                .setTaskRetryTimes(0)
                .setTaskStatus(com.qianli.cashmama.trade.common.enums.TaskStatusEnum.INIT)
                .setTaskType(taskTypeEnum)
                .setTradeNo(tradeNo);
        return tradeTaskCenterRepository.store(tradeTaskCenter);
    }

    /**
     * 展期成功
     *
     * @param tradeBase
     */
    @Override
    public void extensionSuccess(TradeBase tradeBase) {
        tradeBase.transferStatus(com.qianli.cashmama.trade.common.enums.TradeActionEnum.EXTENSION_RECEIPT.getCode(),
                com.qianli.cashmama.trade.common.enums.TradeStatusEnum.REPAYMENT_WATTING.getStatus(), "system", new Date(), new Date(), "SIGN SUCCESS");
    }

    @Override
    public void earlyPayment(TradeBase tradeBase) {
        tradeBase.transferStatus(com.qianli.cashmama.trade.common.enums.TradeActionEnum.PAID_RECEIPT.getCode(),
                com.qianli.cashmama.trade.common.enums.TradeStatusEnum.EARLY_REPAYMENT.getStatus(), "system", new Date(), new Date(), "SIGN SUCCESS");
        tradeBase.setTradeOrderStatus(TradeStatusEnum.EARLY_REPAYMENT);
    }

    @Override
    public void normalPayment(TradeBase tradeBase) {
        tradeBase.transferStatus(com.qianli.cashmama.trade.common.enums.TradeActionEnum.PAID_RECEIPT.getCode(),
                com.qianli.cashmama.trade.common.enums.TradeStatusEnum.NORMAL_REPAYMENT.getStatus(), "system", new Date(), new Date(), "SIGN SUCCESS");
        tradeBase.setTradeOrderStatus(TradeStatusEnum.NORMAL_REPAYMENT);
    }

    @Override
    public void overduePayment(TradeBase tradeBase) {
        tradeBase.transferStatus(com.qianli.cashmama.trade.common.enums.TradeActionEnum.PAID_RECEIPT.getCode(),
                com.qianli.cashmama.trade.common.enums.TradeStatusEnum.OVERDUE_REPAYMENT.getStatus(), "system", new Date(), new Date(), "SIGN SUCCESS");
        tradeBase.setTradeOrderStatus(TradeStatusEnum.OVERDUE_REPAYMENT);
    }

    @Override
    public void loanSuccess(TradeBase tradeBase) {
        tradeBase.transferStatus(com.qianli.cashmama.trade.common.enums.TradeActionEnum.PAID_RECEIPT.getCode(),
                com.qianli.cashmama.trade.common.enums.TradeStatusEnum.REPAYMENT_WATTING.getStatus(), "system", new Date(), new Date(), "loan success");
        tradeBase.setTradeOrderStatus(TradeStatusEnum.REPAYMENT_WATTING);
    }
    @Override
    public void loanConfirmSuccess(TradeBase tradeBase) {
        tradeBase.transferStatus(com.qianli.cashmama.trade.common.enums.TradeActionEnum.WITHDRAWAL_CONFIRM.getCode(),
                com.qianli.cashmama.trade.common.enums.TradeStatusEnum.REPAYMENT_WATTING.getStatus(), "system", new Date(), new Date(), "loan success");
        tradeBase.setTradeOrderStatus(TradeStatusEnum.REPAYMENT_WATTING);
    }

    @Override
    public void overdue(TradeBase tradeBase) {
        tradeBase.transferStatus(com.qianli.cashmama.trade.common.enums.TradeActionEnum.OVERDUE_RECEIPT.getCode(),
                TradeStatusEnum.OVERDUE.getStatus(), "system", new Date(), new Date(), "loan success");
        tradeBase.setTradeOrderStatus(TradeStatusEnum.OVERDUE);
    }
}
